#include <iostream>
using namespace std;

//类模板 就是将类的属性进行类型化 
//目的是实现算法和数据结构的分离

//A编程模板 类
//模板类 类型参数化
template <typename T>
class A
{
protected:
        T a;
public:
        A(T a = 0){
                this->a = a;
        }
public :
        void printA(){
                cout<<"a = "<<a<<endl;
        }
};

//类模板 做函数参数
//参数 c++编译器 要求具体的类 所以  要A<int> &a
void UserA(A<int> &a){
        a.printA();
}

int main01(int argc, char const *argv[]){
        //模板类(本身就是类型化的) ====》 具体的类 ====》 定义具体的变量

        A<int> a1(11), a2(20), a3(30); //模板类是抽象的 ===》需要进行 类型具体 
        a1.printA();
        
        UserA(a1);
        UserA(a2);
        UserA(a3);

        return 0;
}

//从模板类派生普通类
//模板类派生时,需要具体化模板类, c++编译器需要知道 父类的数据类型具体是什么样子的
//====>要知道父类所占的内存大小是多少 只有数据类型固定下来,才知道如何分配内存
class B : public A<int>{
private:
        int b;
public:
        B(int a=10, int b = 20):A<int>(a){
                this->b = b;
        }
        void printB(){
             cout<<"a = "<<a<<" b = "<<b<<endl;   
        }
};

int main02(int argc, char const *argv[]){
        B b1(1,2);
        b1.printB();
        return 0;
}

//从模板类派生模板类
template <typename T>
class C : public A<T> 
{
protected:
        T c;
public:
        C(T c, T a) : A<T>(a){
                this->c = c;
        }

        void printC(){
                cout<<"a = "<< this->a<<" c = "<<c<<endl;   
        }
};

int main(int argc, char const *argv[]){
        C<int> c1(10, 20);
        c1.printC();
        return 0;
}


